AWS黎明期のベストプラクティスを改めて読み返すことで、クラウドのためのアーキテクチャー大原則を再確認する
西澤です。最近AWSの進化が凄まじすぎて、そもそもついていけない選択肢が多すぎるし、設計難しいよなーって思うことが増えています。もうAWS上で動かすことができないシステムはほぼ無くなりつつあるのが現状だとは思いますが、それでもやはりクラウドとの親和性が高いシステムとそうでないシステムがあることも事実だし、そもそもの大原則を復習することで、本来想定されていたあるべき姿を抑えておくことには意味があるんじゃないかと考えています。そこで、私が初めてAWSを知ったときに衝撃を受けた資料を読み返してみたところ、シンプルで非常に重要な原則が書かれていることを再確認できたので、ここで改めてご紹介したいと思いました。
ご紹介したい資料
私がクラスメソッドにジョインしたときに書いたブログでもご紹介させていただいたのですが、今回ご紹介するのは、当時AWSのエバンジェリストだった玉川さん、ソリューションアーキテクトだった大谷さんの2011年5月のウェビナー資料です(私がこの資料を初めて読んだのは何年も後のことですが)。時代的には、Tokyoリージョンが開設された直後に、東日本大震災が起きたというタイミング。さらに調べてみると、AWSサービスとしては、IAMがリリースされたばかり、Direct ConnectやVPCはまだ正式リリースされていない状況だったようです(今となってはこれらのサービスが存在しないAWSを想像するのは難しいと思いますが)。
クラウドコンピューティングの特徴
- 抽象化されたリソース
- 必要なときに瞬時に調達
- スケールアウト自由自在
- 従量課金
- 自動化
まずは、"いつでも、必要なだけ、安価に、コンピュータリソースを利用可能"というメッセージの通り、拡張性(Scalability)・弾力性(Elasticity)の恩恵を受ける為に、"クラウドの制約"をトレードオフとして受け入れようというメッセージが書かれています。先程ご紹介した通り、この時点のAWSでは制約事項が非常に多く存在していた為、ここは苦しいところもあったと思います。ただ、制約が多かったが故に選択肢が少なかったので、ユーザーが判断できることは受け入れるか、否か、しか無かったのではないかと思います。
一方で、"弾力性のあるアーキテクチャは芸術的"という表現でエンジニア向けにあえてエモいメッセージを送っているところがすごく気に入っています。アーキテクチャ設計がアートなのかはわかりませんが、作っていて楽しい、動かしてみて面白いという気持ちは、ものづくりの原点なのではないかと思います。イベント駆動アーキテクチャ、サーバレスアーキテクチャの考え方も、クラウドという前提があったからこそ、生まれたことは言うまでもありません。
また、その弾力性を実現する為にAWSに今でも一貫しているのが、プログラマブルに操作できるよう設計されていることです。AWSにおけるほぼすべての操作について、APIベースで操作できることは今となっては当たり前になりましたが、開発者たちが願っていたインフラをプログラムを使って自由に調達できる仕組みを公開したのですから、熱狂的に受け入れられたことも当然だったと思います。
クラウドのためのアーキテクチャ設計ベストプラクティス
ということで、本題のアーキテクチャ設計ベストプラクティスです。この部分をAWS設計に関わる多くの方に改めて読んでもらえたら嬉しいなと思います。
1. 故障のための設計(Design for faiure)
まず、誤解の無いようにお伝えしたいことがあります。「AWSって障害が多いんですよね?」って、今でもAWSを初めて利用されるお客さまによく質問されるのですが、そんなことは決してありません。見えない領域で起こる障害に対して不信感を持ってしまうことは当然ですし、自分たちでコントロールできない領域で発生する障害に遭遇した際のストレスが大きいことは人間なので仕方がありませんが、総じて見れば利用者側に影響が及ぶようなAWS基盤の障害発生率、故障率は非常に低いものです。まあ具体的なデータがあるわけではないのですが、オンプレと同様当たり外れがあるのはある程度仕方のないことですし、たとえハズレを引いたとしても、ワンクリックで新しいインフラを調達できるので、結果として故障による影響を受ける可能性が大きく下がっていることは間違いないと思います。
その上でさらに、単一障害点(SPOF)は作らない、故障したとしても自動的に復旧したり、サービスを提供し続けるような設計をしましょうっていうのが、この"Design for failure"という考え方です。システムのRTO/RPOに応じてアプローチを決めることになりますが、例えばAWSではMultiAZを活用して極めて可用性の高い仕組みを短時間で用意することができますので、これを活用しない手はありません。逆に注意が必要となる点としては、クラウドでは開放したリソースを取り戻すことができないと考えて設計すべきですから、障害や誤操作によってデータを失わない為に必要なログやデータの退避、バックアップをしっかり行っておく必要があります。
2. 疎結合なコンポーネント
"疎結合"という言葉も、現在ではマイクロサービスアーキテクチャと合わせて、一般的になってきていると思いますが、当時はまだそこまで浸透していない考え方だったように思います(私が勉強不足だっただけかもしれませんが、今と比較すれば間違いないかと)。クラウドのアーキテクチャーを考える上で、コンポーネントの独立性を維持する為に処理を非同期にできるものはなるべく非同期にするという考え方が、非常に重要だと考えています。SQSがAWSサービス史上2番目(S3の次、EC2より前)にリリースされたサービスであることを知らない方も多いと思いますが、歴史的に見ても重要度が高いサービスだったということがわかります。
3. 弾力性の実装
拡張性(Scalability)・弾力性(Elasticity)を獲得する為に、当時革新的だったAutoScalingの実装に対しての課題を詳しく説明しています。インスタンス起動時に動的に設定できるようにすることで、すべてのインスタンスが常に意図した状態で起動することを維持する仕組みを理解しておくこと、また、逆にいつでも捨てられるようにしておくことが重要です。現在では、コンテナベースのインフラ技術を利用して、さらにアジリティの高い置き換え可能なインフラを利用することができるようになりました。
4. 全レイヤにおけるセキュリティ担保
セキュリティについては、"責任共有モデル"の考え方がかなり浸透してきたと思います。セキュリティの責任境界線を正しく理解し、クラウドサービス側に任せられることは任せてしまい、ユーザ側の責任で守るべきものをしっかり守ることが重要となります。「セキュリティは常に最優先事項である」とは、AWSから頻繁に発信されているメッセージです。当時のセキュリティ関連機能はやや物足りない印象もありましたが、現在までに取得された各種認定やリリースされたセキュリティ機能の拡充を見ると、それもうなずけます。多くの企業の実績が公開され、クラウドに対するユーザの漠然とした不安を払拭する為にセキュリティ対策が徹底されてきたことで、「クラウドだとセキュリティが不安」という声も随分減ったと感じています。
5. 並列処理の使い倒し
疎結合なアーキテクチャとも関連するところがありますが、処理をシーケンシャルにせず、並列処理できるように工夫することもクラウドの登場とともに根付いた考え方だと思います。分散コンピューティングを利用したい場合、クラウド以前はある程度高価かつ大量のコンピューティングリソースを物理的に用意する必要がありましたが、現在では必要なリソースを必要なときにだけ利用できるクラウド上で利用することができます。また、処理を並列化しておくことで、取り扱う処理量が急に増えても簡単にスケールさせることができますし、長時間かかっていた処理を短時間で済ますことができるようになります。現在では、サーバレスアーキテクチャで利用されるスケーラブルなサービスを中心に、有用なマネージドサービスを組み合わせた並列処理が一般的になってきたと思います。
6. 異なるストレージの使い分け
ひと昔前のオンプレミスにあった業務システムでは、データはとりあえずOracle RACに入れておこうみたいな使い方が多かったのではないかと思います(※やや先入観が強いかもしれませんが、実際にそのような使われ方を何例も見たことがあります)。商用データベースは高機能なので、アプリケーションや利用者が多少雑な使い方をしてもそれなりのパフォーマンスを発揮してくれますが、クラウドではデータの置き場所は用途に合わせて適切に選んで配置する必要があります。それぞれのストレージサービスの特性をよく理解した上で設計することが重要なのですが、現状のAWSサービスにおけるその選択肢の多さたるや、、、。データストレージは一旦運用が始まってしまうと、後から手を入れることができないケースも多いので、設計段階での十分検討が必要です。また最近では、S3をデータレイクとしてデータストレージの中心に配置して、必要な情報のみを取り出して活用するような使い方も増えて来ています。
まとめ
偉大なレジェンドたちが作ってくれた資料を、僭越ながら主観を添えてご紹介させていただきました。現在のAWSサービスでは当時あったような様々な制約が無くなり、より自由度の高いシステム構築が可能となっていますので、必ずこうしなければいけないというものではないのですが、今後よりクラウドネイティブなアーキテクチャを目指して改修を続ける予定のシステムであれば、これらの考え方を考慮に入れた上で再検討すると良いのではないかと思います。ただまあちょっと情報が古すぎますので、細かい情報は読み飛ばしてもらえればと。
参考として、クラウドにおける考え方は、名著「UNIXという考え方」にも通ずるところが多分にあると思っていて、小さいプログラムを組み合わせて使う考え方は、クラウドサービスを部品のように組み合わせてシステムを作る考え方と似ているし、並列処理やマイクロサービスといった考え方の元となっている部分もあるのではないでしょうか。また、「90%の人に受け入れられる解を目指す」というような、開発スタイルの考え方はAWSのサービス作りにも見られますし、「早期に試す」ことはクラウドが前提となった世界の中で我々も積極的に挑戦しているところです。有名な本なので、既にお読みの方も多いと思いましたが、ご紹介しておきます。
はい、言われなくてもわかっています。老害おじさんみたいな記事書いてないで、新しい技術のキャッチアップもがんばっていきます。
どこかの誰かのお役に立てれば嬉しいです。